package com.bsoft.gol.editor.controller;

import com.alibaba.fastjson.JSONObject;

import hcn.util.BaseResponse;
import com.bsoft.gol.editor.editor.ImportLog;
import com.bsoft.gol.editor.model.ImportResult;
import com.bsoft.gol.editor.model.ImportVo;
import com.bsoft.gol.editor.model.UploadFieldNameEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.bsoft.gol.editor.service.ExcelDataImportService;
import com.bsoft.gol.editor.service.ImportLogService;
import com.bsoft.gol.editor.service.impl.DefaultExeclDataImportService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * xlsx格式数据导入导出controller
 * @author 王智伟
 *
 */
@Controller
@RequestMapping(value = "/admin/bas")
public class DataImportAndExportController {

    private final static Logger logger = LoggerFactory.getLogger(DataImportAndExportController.class);
	@Autowired
	private ExcelDataImportService excelDataImportService;
	@Autowired
	private ImportLogService importLogService;
	@Autowired
	private DefaultExeclDataImportService defaultExeclDataImportService;


	@RequestMapping(value={"/import/xlsx"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
	@ResponseBody

	public Map<String,Object> upload(HttpServletRequest request, HttpServletResponse response, ImportVo importVo) {
		logger.info("基础数据导入服务:开始.....");
		long start = System.currentTimeMillis();
		Map<String,Object> resultMap = new HashMap<>();
		if (request == null) {
			response.setStatus(400);
			resultMap.put("code",400);
			resultMap.put("msg","没有提交文件");
			return resultMap;
		}
		ImportResult result = null;
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		try {
//			MultiValueMap<String, MultipartFile> fileMap = multipartRequest.getMultiFileMap();
//			Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
			MultiValueMap<String, MultipartFile> fileMap = multipartRequest.getMultiFileMap();
			for(String key : fileMap.keySet()){
				System.out.print("key="+key);
				importVo.setDataType(key);
				result = uploadData(importVo, (List<MultipartFile>) fileMap.get(key));
				break;
			}
			if(result != null){
				resultMap.put("code", 200);
				List<FailLog> failData = new ArrayList<>();
				FailLog failLog = new FailLog();
				ImportLog log = result.getLog();
				failLog.setFail(result.getFailCount());
				failLog.setFileName(importVo.getFileName());
				failLog.setTakeMs(log.getTakeMs());
				failLog.setTotal(log.getTotal());
				if(log != null){
					failLog.setId(log.getId());
					failLog.setOpDate(log.getCreatedDate());
				}
				failData.add(failLog);
				resultMap.put("body", log);
			}
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
			logger.error("基础数据导入服务:发生异常:" + e.getLocalizedMessage());
			resultMap.put("code",500);
			resultMap.put("msg", "导入数据过程发生异常，请检查后重试");
		}
		long end = System.currentTimeMillis();
		logger.info("基础数据导入服务:结束，耗时" + (end - start) + "ms，返回结果:" + JSONObject.toJSONString(resultMap));
		return resultMap;
	}
	/**
	 * 根据数据类型查询存在失败数据的导入日志
	 * @param dataType 数据类型
	 * 	 * <ul>数据类型:
	 *  <li>uploadOrg:导入机构</li>
	 *  <li>uploadDept:导入科室</li>
	 *  <li>uploadDoctor:导入医生</li>
	 *  <li>uploadTeam:导入团队</li>
	 *  <li>uploadMember:导入团队成员</li>
	 *  <li>uploadSign:导入居民签约记录</li>
	 *  <li>uploadService:导入基础服务项记录</li>
	 * </ul>
	 * @return 没完全导入数据的、但没有下载的 导入日志的记录集合
	 */
	@RequestMapping(value={"/import/qryFailLogs"})
	@ResponseBody
	public Map<String,Object> qryImportLog(String dataType){
		logger.info("基础数据导入日志查询:类型[" + dataType + "]...");
		Map<String,Object> result = new HashMap<>();
		try {
			List<ImportLog> logList = importLogService.queryLogNotDownloadByDataType(dataType);
			List<FailLog> failData = new ArrayList<>();
			if(logList != null && logList.size() > 0){
				for(ImportLog log : logList){
					FailLog item = new FailLog();
					item.setId(log.getId());
					item.setFileName(log.getFileName());
					item.setTotal(log.getTotal());
					item.setFail(log.getFail());
					item.setOpDate(log.getCreatedDate());
					item.setTakeMs(log.getTakeMs());
					failData.add(item);
				}
			}
			result.put("body", failData);
			result.put("code", 200);
		} catch (Exception e) {
			result.put("code", 500);
			result.put("msg", "系统操作异常:" + e.getMessage());
			e.printStackTrace();
			logger.error("基础数据导入日志查询:发生异常:" + e.getMessage());
		}
		logger.info("基础数据导入日志查询:操作结束，结果:" + JSONObject.toJSONString(result));
		return result;
	}
	
	/**
	 * 根据ID下载失败的数据的表格
	 * 根据ID查询出日志中存储的failJson，然后写入一个excel提供下载
	 * @param id 记录ID
	 * @return excel输出文件流
	 */
	@RequestMapping(value={"/import/download"})
	public ResponseEntity<byte[]> download(int id){
		logger.info("基础数据导入导入失败的内容下载:失败的导入日志ID:" + id);
		ImportLog log = importLogService.getLogById(id);
		byte[] data = excelDataImportService.writeExcel(id,"");
		if(data != null){
			HttpHeaders headers = new HttpHeaders();
			String fileName = "导入失败数据-" + log.getFileName();
		    try {
				fileName = URLEncoder.encode(fileName,"utf-8");
				headers.add("Content-Disposition", "attchement;filename=" + fileName + ";filename*=utf-8'zh_cn'" + fileName);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				logger.error("基础数据导入的模板下载:发生异常:" + e.getMessage());
			}
	        headers.add("Content-Type", "application/vnd.ms-excel;charset=UTF-8");
		    HttpStatus statusCode = HttpStatus.OK;
		    ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(data, headers, statusCode);
		    logger.info("基础数据导入导入失败的内容下载:结束");
		    return entity;
		}
		logger.info("基础数据导入导入失败的内容下载:导出内容为空，结束。");
		return null;
	}


	@RequestMapping("/logs")
    @ResponseBody
	public BaseResponse logs(@RequestBody ImportLog importLog) {

		BaseResponse  baseResponse =new BaseResponse();
		ImportLog log = importLogService.getLogById(importLog.getId());
		baseResponse.setData(log);


		return baseResponse;
	}
//
//	@RequestMapping(value={"/import/download"})
//	public ResponseEntity<byte[]> download(int id,String dataType){
//		logger.info("基础数据导入导入失败的内容下载:日志ID:" + id);
//		byte[] data = defaultExeclDataImportService.writeExcel(id,dataType);
//		ImportLog log = importLogService.getLogById(id);
//		if(data != null){
//			HttpHeaders headers = new HttpHeaders();
//			String fileName = "导入失败数据-" + log.getFileName();
//			try {
//				fileName = URLEncoder.encode(fileName,"utf-8");
//				headers.add("Content-Disposition", "attchement;filename=" + fileName + ";filename*=utf-8'zh_cn'" + fileName);
//			} catch (UnsupportedEncodingException e) {
//				e.printStackTrace();
//				logger.error("数据导入的模板下载:发生异常:" + e.getMessage());
//			}
//			headers.add("Content-Type", "application/vnd.ms-excel;charset=UTF-8");
//			HttpStatus statusCode = HttpStatus.OK;
//			ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(data, headers, statusCode);
//			logger.info("数据导入导入失败的内容下载:结束");
//			return entity;
//		}
//		logger.info("基础数据导入导入失败的内容下载:导出内容为空，结束。");
//		return null;
//	}
	/**
	 * 根据ID下载失败的数据的表格
	 * 根据ID查询出日志中存储的failJson，然后写入一个excel提供下载
	 * @param id 记录ID
	 * @return excel输出文件流
	 */
	@RequestMapping(value={"/import/template"})
	public ResponseEntity<byte[]> downloadTemplate(@RequestParam String dataType, HttpServletResponse response){
		logger.info("基础数据导入的模板下载:模板类型:" + dataType);
		byte[] data = null;
		String fileName = "导入" + UploadFieldNameEnum.getText(dataType) + "模板.xls";
		logger.info("基础数据导入的模板下载:导出的文件名:" + fileName);
		data = excelDataImportService.writeExcel(0,dataType);
		if(data != null){
			HttpHeaders headers = new HttpHeaders();
		    try {
				fileName = URLEncoder.encode(fileName,"utf-8");
				headers.add("Content-Disposition", "attchement;filename=" + fileName + ";filename*=utf-8'zh_cn'" + fileName);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				logger.error("基础数据导入的模板下载:发生异常:" + e.getMessage());
			}
	        headers.add("Content-Type", "application/vnd.ms-excel;charset=UTF-8");
		    HttpStatus statusCode = HttpStatus.OK;
		    ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(data, headers, statusCode);
		    logger.info("基础数据导入的模板下载:导出操作结束");
		    return entity;
		}
		logger.info("基础数据导入的模板下载:返回空");
		return null;
	}
	
	/**
	 * 导入数据普通方法
	 * 除了居民签约数据导入外，如机构、科室、团队、团队成员、中医疾病、西医疾病的数据导入都调用此方法
	 * @param fileItemList
	 * @param importVo
	 * @return 导入结果
	 * @throws IOException
	 * @throws InterruptedException
	 */
	private ImportResult uploadData(ImportVo importVo,List<MultipartFile> fileItemList)
			throws IOException, InterruptedException{
		logger.info("uploadData:fileItemList.size:" + ( fileItemList == null ? 0 : fileItemList.size()));
		if(fileItemList != null && fileItemList.size() > 0){
			MultipartFile multipartFile = fileItemList.get(0);
			String fileName = multipartFile.getOriginalFilename();
			logger.info("fileName:" + fileName);
			importVo.setFileName(fileName);
			BufferedInputStream bis = new BufferedInputStream(multipartFile.getInputStream());
			byte[] buffer = new byte[10240];
			logger.info("inputstream : " + multipartFile.getSize() + "|" + multipartFile.getInputStream().available());
			byte[] data = new byte[multipartFile.getInputStream().available()];
			int len = 0;//读取到的数据
			int offset = 0;
			while((len = bis.read(buffer)) > 0){
				System.arraycopy(buffer, 0, data,offset , len);
				offset = offset + len;
			}
			importVo.setData(data);
		}
		logger.info("data size:" + (importVo.getData() == null ? 0: importVo.getData().length));
		ImportResult result = excelDataImportService.importData(importVo);
		return result;
	}
	
	
	static class FailLog{
		private int id;//日志ID
		private String fileName;//文件名称
		private int total;//总条数
		private int fail;//失败条数
		private Date opDate;//操作时间
		private long takeMs;//花费时间[毫秒数]
		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}
		public String getFileName() {
			return fileName;
		}
		public void setFileName(String fileName) {
			this.fileName = fileName;
		}
		public int getTotal() {
			return total;
		}
		public void setTotal(int total) {
			this.total = total;
		}
		public int getFail() {
			return fail;
		}
		public void setFail(int fail) {
			this.fail = fail;
		}
		public Date getOpDate() {
			return opDate;
		}
		public void setOpDate(Date opDate) {
			this.opDate = opDate;
		}
		public long getTakeMs() {
			return takeMs;
		}
		public void setTakeMs(long takeMs) {
			this.takeMs = takeMs;
		}
	}
}
